<?php

require_once dirname(__FILE__).'/../lib/ticketGeneratorConfiguration.class.php';
require_once dirname(__FILE__).'/../lib/ticketGeneratorHelper.class.php';

/**
 * ticket actions.
 *
 * @package    ti
 * @subpackage ticket
 * @author     Evgeny Babin <psylosss@gmail.com>
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class ticketActions extends autoTicketActions
{
  function preExecute()
  {
    parent::preExecute();
    
    //проверка, выбран ли текущий проект?
    
  }
  
  private function createTicketById($id)
  {
    $ticket=TicketQuery::create()->joinProject()->joinCurrentUser()->joinVisibleToUsers()->filterById($id)->fetchOne();
    
    $is_visible=$ticket->isVisibleToUser($this->getUser()->getGuardUser()->Profile);
    
    $this->forward404Unless($ticket, sprintf('Тикет не найден (%s).', $id));
    
    $this->forward404Unless($is_visible, 'Просмотр тикета не разрешен.');
    
    return $ticket;
  }

  
  function executeShow(sfWebRequest $request)
  {
    $this->ticket=$this->createTicketById($request->getParameter('id'));
    
    //Загружаем сообщения
    $q=MessageQuery::create()->joinTicket()->filterByTicketId($this->ticket->id)->joinUser()->onlyVisible();
    $this->messages=$q->execute();
      
    $this->form=new MessageForm(null,array('ticket'=>$this->ticket),false);
    $this->form->setDefaults(array(
      'visible_to_users_list'=>$this->ticket->getVisibleToUsers()->getPrimaryKeys(),
      'ticket_id'=>$this->ticket->id,
    ));
  }
  
  
  function executeMessageNew(sfWebRequest $request)
  {
    $this->forward404Unless($request->isMethod('post'),'Недопустимое обращение к странице');
   
    //Ой как некрасиво...
    $message_holder=$request->getParameter('message');
    $this->ticket=$this->createTicketById($message_holder['ticket_id']);
    
    $this->form=new MessageForm(null,array('ticket'=>$this->ticket),false);
    $this->form->bind($request->getParameter($this->form->getName()));
    if ($this->form->isValid())
    {
      $message=$this->form->save();
      
      //Отправляем письмо всем заинтересованным: тому, кто видит сообщение + кто управляет всеми тикетами
      $emails=array();
      foreach ($message->VisibleToUsers as $user)
        $emails[$user->email]=$user->fullname;
        
      $users=UserQuery::create()->filterByPermissions(array('manage_tickets_in_own_projects','manage_tickets_in_all_projects'))->execute();
      
      foreach ($users as $user)
        $emails[$user->Profile->email]=$user->Profile->fullname;
      
      
      //Не отправляем письмо самому себе
      unset($emails[$this->getUser()->getGuardUser()->Profile->email]);
        
      
      foreach ($emails as $email=>$fullname)
      {
        $this->mail(array(
          'subject' => 'Ответ в тикете #'.$this->ticket->id.' ['.$this->ticket->title.'] от '.$this->getUser()->getGuardUser()->username,
          'email' => $email,
          'fullname' => $fullname,
          'parameters' => array(
            'message'=>$message,
            'ticket'=>$this->ticket,
            ),
          'text' => 'ticket/newMessageText',
          'html' => 'ticket/newMessageHtml'));
      }
      
      $this->redirect('@ticket_show?id='.$this->ticket->id);
    }
    
    
    
    $this->setTemplate('show');
  }
  
  function executeOpenClose(sfWebRequest $request)
  {
    $this->ticket=$this->createTicketById($request->getParameter('id'));
    
    $is_open_close_allowed=$this->ticket->isOpenCloseAllowedBy($this->getUser()->getGuardUser()->Profile);
    $this->forward404Unless($is_open_close_allowed,'Не хватает прав закрыть тикет');
    
    $this->ticket->is_closed=$request->getParameter('open_close')=='close' ? true:false;
    $this->ticket->save();
    
    //Добавляем сообщение в тикет
    $message=new Message();
    $message->ticket_id=$this->ticket->id;
    $message->user_id=$this->getUser()->getGuardUser()->Profile->id;
    $message->text=$this->ticket->is_closed ? 'Закрываю тикет' : 'Снова открываю тикет';
    $message->save();
    
    //TODO: надо записать в БД, кому видно это системное сообщение
    
    
    //Если закрыли - идем в список тикетов. Если открыли - остались в тикете.
    if ($this->ticket->is_closed)
      $this->redirect('@ticket');
    else
      $this->redirect('@ticket_show?id='.$this->ticket->id);  
  }

  //Потребовалось оверрайдить этот метод только для того, чтобы после сохранения перенаправлялось на ticket_show. Есть идеи получше?
  //А еще письма отправить после создания тикета...
  protected function processForm(sfWebRequest $request, sfForm $form)
  {
    $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
    if ($form->isValid())
    {
      $notice = $form->getObject()->isNew() ? 'The item was created successfully.' : 'The item was updated successfully.';

      try {
        $ticket = $form->save();
      } catch (Doctrine_Validator_Exception $e) {

        $errorStack = $form->getObject()->getErrorStack();

        $message = get_class($form->getObject()) . ' has ' . count($errorStack) . " field" . (count($errorStack) > 1 ?  's' : null) . " with validation errors: ";
        foreach ($errorStack as $field => $errors) {
            $message .= "$field (" . implode(", ", $errors) . "), ";
        }
        $message = trim($message, ', ');

        $this->getUser()->setFlash('error', $message);
        return sfView::SUCCESS;
      }
      
      
      //Отправляем письмо всем заинтересованным: тому, кто видит тикет + кто управляет всеми тикетами
      $emails=array();
      foreach ($ticket->VisibleToUsers as $user)
        $emails[$user->email]=$user->fullname;
        
      $users=UserQuery::create()->filterByPermissions(array('manage_tickets_in_own_projects','manage_tickets_in_all_projects'))->execute();
      
      foreach ($users as $user)
        $emails[$user->Profile->email]=$user->Profile->fullname;
      
      
      //Не отправляем письмо самому себе
      unset($emails[$this->getUser()->getGuardUser()->Profile->email]);
        
      
      foreach ($emails as $email=>$fullname)
      {
        $this->mail(array(
          'subject' => 'Новый тикет #'.$ticket->id.' ['.$ticket->title.'] от '.$this->getUser()->getGuardUser()->username,
          'email' => $email,
          'fullname' => $fullname,
          'parameters' => array(
            'ticket'=>$ticket,
            'message'=>$ticket->Messages[0],
            ),
          'text' => 'ticket/newText',
          'html' => 'ticket/newHtml'));
      }
      
      
      

      $this->dispatcher->notify(new sfEvent($this, 'admin.save_object', array('object' => $ticket)));

      if ($request->hasParameter('_save_and_add'))
      {
        $this->getUser()->setFlash('notice', $notice.' You can add another one below.');

        $this->redirect('@ticket_new');
      }
      else
      {
        $this->getUser()->setFlash('notice', $notice);

        $this->redirect(array('sf_route' => 'ticket_show', 'sf_subject' => $ticket));
      }
    }
    else
    {
      $this->getUser()->setFlash('error', 'The item has not been saved due to some errors.', false);
    }
  }  
  
  /*
    @options -
  */
  function mail($options)
  {
    $required = array('subject', 'parameters', 'email', 'html', 'text');
    foreach ($required as $option)
    {
      if (!isset($options[$option]))
      {
        throw new sfException("Required option $option not supplied to mail");
      }
    }

    $message=Swift_Message::newInstance()
      ->setFrom(array(sfConfig::get('app_from_mail_email')=>sfConfig::get('app_from_mail_fullname')))
      ->setTo(array($options['email']=>$options['fullname']))
      ->setSubject($options['subject'])
      ;

    $message->attach($this->createContentAttachment($this->getPartial($options['html'], $options['parameters']), 'text/html'));
    $message->attach($this->createContentAttachment($this->getPartial($options['text'], $options['parameters']), 'text/plain'));

    $message->setEncoder(Swift_Encoding::get8BitEncoding());
    
    $this->getMailer()->send($message);
  }
  
  protected function createContentAttachment($content, $content_type='text/html')
  {
    $part = Swift_MimePart::newInstance($content, $content_type);
    $part->setEncoder(Swift_Encoding::get8BitEncoding());
    return $part;
  }
  
  
}
